home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / scan21.zip / SCAN.PAS < prev    next >
Pascal/Delphi Source File  |  1988-07-05  |  12KB  |  395 lines

  1. Program Scan;
  2. {$D-}
  3. {  SCAN.PAS - A utility to scan binary files for text strings.
  4.  
  5. Usage:  SCAN [-<offswitches>] [+<onswitches>] [input file] [output file]
  6. where:    <offswitches> is the list of switches to turn off,
  7.           <onswitches> is the list of switches to turn on, and
  8.           input file and output file are the source and dest. files.
  9.           To specify an output file you must give an input file.
  10.           If either is not specified, SCAN will use stdin/stdout so
  11.           you can also use command-line redirection.
  12.  
  13. or SCAN ? 
  14.      for a list of switches.
  15.  
  16. For a complete list of switches, see the accompanying documentation.
  17.  
  18. Switches are processed left-to-right both within and between + and - groups.
  19.  
  20. Notes:  The default minimum string length is 4 characters.  The maximum
  21. possible string length is 255 and any which run over will be cut into 255-
  22. har lengths.
  23.  
  24. This program is public domain.  Knock yourself out.
  25. }
  26.  
  27. uses Ecase;  { International version of UpCase }
  28.  
  29. type
  30.      SwitchList = record
  31.           DispEsc, DispTab, ConvTab, DispCR, DispLF, DispFF, AllowNull,
  32.           DispNull, ForceNull, StripLead, StripTrail, HighOk, GraphicOk, 
  33.           ForeignOk, Extended, StripHiIn, ConvSpace, UpperCase, English, 
  34.           ConvBslash, ConvHiNum, ConvHiDot, ShortLine: boolean;
  35.      end;
  36.  
  37.      filename = string[80];      {Input/output files if not stdin/stdout}
  38.      msgstring = string[75];
  39.      HighChars = #128..#255;
  40.      Printset = set of HighChars;
  41. var
  42.      ifile, ofile: filename;
  43.      Sw: SwitchList;
  44.      MinLen: byte;
  45.      Infile: file of char;
  46.      Outfile: text;
  47.  
  48. Const
  49.      ForeignSet: PrintSet = [#128..#154, #160..#165, #168, #173..#175];
  50.      GraphicSet: PrintSet = [#176..#223];
  51.      HibitSet: PrintSet = [#128..#255];
  52.  
  53.      Short = 72;         { Short line length S+ }
  54.      Long = 255;         { Long line length S- }
  55.      SpaceReplace = '_'; { Char to replace Space on ConvSpace }
  56.      DotReplace = '.';   { Char to replace hi-bit on ConvHiDot }
  57.      DefMin = 4;         { Default minimum line length }
  58.      DefInput = '';      { Default input file (console)}
  59.      DefOutput = '';     { Default output file (console)}
  60.  
  61.      Copyright1: MsgString = 
  62. ' SCAN Version 2.1 05-Jul-88 by Kenneth Herron. Placed in the public domain.';
  63. {=============================}
  64. procedure DoHelp;
  65.  
  66. begin
  67.      writeln(Copyright1);
  68.      writeln;
  69.      writeln('Usage: SCAN [-off] [+on] [infile [outfile]]');
  70.      writeln('Switches are:');
  71.      writeln('$  Translate ESC to \$    \  Translate \ to \\');
  72.      writeln('C  Translate CR to \C     L  Translate LF to \L');
  73.      writeln('F  Translate FF to \F     @  Translate TAB to \T');
  74.      writeln('T  Make TAB printable     H  Make ascii 128-255 printable');
  75.      writeln('0  Make NULL printable    ?  Make foreign chars printable');
  76.      writeln('!  Str must end in NULL   G  Make graphic chars printable');
  77.      writeln('%  Strip hi bit (input)   E  Str must have vowel & consonant');
  78.      writeln('{  Strip leading spaces   }  Strip trailing spaces');
  79.      writeln('U  Upper-case output      B  Translate space to ', SpaceReplace);
  80.      writeln('.  Convert hi-bit to ', DotReplace, 
  81.                                    '    #  Convert hi-bit to ASCII');
  82.      writeln('S  Max string length is (-)', Long:3,
  83.              ' or (+)', Short:2,' characters');
  84.      writeln;
  85.      halt;
  86. end;
  87.  
  88. {=============================}
  89. procedure SetSwitches(var Ifile, Ofile: Filename; 
  90.                       var SW: Switchlist; var MinLen: byte);
  91.  
  92. var
  93.      T: filename;
  94.      H, I: byte;
  95.      J: integer;
  96.      Setting: boolean;
  97.  
  98. begin
  99. { Set default switches }
  100. fillchar(SW, SizeOf(SW), false);
  101. with sw do
  102. begin
  103.      DispTab := true;
  104.      StripLead := true;
  105.      ShortLine := true;
  106. end;
  107. for H := 1 to ParamCount do
  108. begin
  109.      T := paramstr(H);
  110.      if (T[1] = '+') or (T[1] = '-') then
  111.      begin
  112.           Setting := T[1] = '+';
  113.           for I := 2 to length(T) do
  114.           with sw do
  115.           case upcase(T[I]) of
  116.           'B': ConvSpace := setting;
  117.           'E': English := setting;
  118.           '\': ConvBslash := setting;
  119.           '$': begin
  120.                     DispEsc := setting;
  121.                     ConvBslash := setting or ConvBslash;
  122.                end;
  123.           'T': begin
  124.                     DispTab := setting;
  125.                     ConvBslash := setting or ConvBslash
  126.                end;
  127.           '@': begin
  128.                     ConvTab := setting;
  129.                     DispTab := setting;
  130.                     ConvBslash := setting or ConvBslash
  131.                end;
  132.           '0': begin
  133.                     DispNull := setting;
  134.                     ConvBslash := setting or ConvBslash
  135.                end;
  136.           '!': ForceNull := setting;
  137.           '{': StripLead := setting;
  138.           '}': StripTrail := setting;
  139.           'H': begin
  140.                     HighOk := setting;
  141.                     GraphicOk := (not setting) and GraphicOk;
  142.                     ForeignOk := (not setting) and ForeignOk
  143.                end;
  144.           '?': begin
  145.                     ForeignOk := setting;
  146.                     HighOk := (not setting) and HighOk
  147.                end;
  148.           'G': begin
  149.                     GraphicOk := setting;
  150.                     HighOk := (not setting) and HighOk
  151.                end;
  152.           'U': UpperCase := setting;
  153.           'C': begin
  154.                     DispCr := setting;
  155.                     ConvBslash := setting or ConvBslash
  156.                end;
  157.           'L': begin
  158.                     DispLf := setting;
  159.                     ConvBslash := setting or ConvBslash
  160.                end;
  161.           'F': begin
  162.                     DispFF := setting;
  163.                     ConvBslash := setting or ConvBslash
  164.                end;
  165.           '#': begin
  166.                     ConvHiNum := setting;
  167.                     ConvBslash := setting or ConvBslash
  168.                end;
  169.           '.': ConvHiDot := setting;
  170.           '%': StripHiIn := setting;
  171.           'S': ShortLine := setting;
  172.           '1'..'9':
  173.                MinLen := ord(T[I]) and 15;
  174.           end
  175.      end
  176.      else { File name }
  177.           if ifile = '' then
  178.                ifile := T
  179.           else
  180.           if ofile = '' then
  181.                ofile := T
  182. end;
  183.  
  184. {perform some housekeeping}
  185. with SW do
  186. begin
  187.      if StripHiIn then
  188.      begin
  189.           HighOk := false;
  190.           ForeignOk := false;
  191.           GraphicOk := false
  192.      end;
  193.      AllowNull := DispNull or ForceNull;
  194.      Extended := HighOk or ForeignOk or GraphicOk
  195. end;
  196. end;  {procedure SetSwitches}
  197. {=============================}
  198. procedure Process;
  199.  
  200. type
  201.      MaxString = string[255];
  202.  
  203. var
  204.      Len: byte;               { Max Length of a string }
  205.      Str: MaxString;
  206.      ch: char;
  207.      Printable: PrintSet;
  208.      StopStr: boolean;
  209.      HighValid: PrintSet;
  210.  
  211. Function Validate(var Str: maxstring): boolean;
  212.  
  213. { check any built strings to see if they shouldn't be printed for
  214. some reason.  Currently two options are checked--E (must contain a
  215. consonant & vowel) and ! (must end in NULL).  Strings may also be
  216. rejected for being too short but we don't check that here. }
  217.  
  218. var foundc, foundv: boolean;
  219.     I: byte;
  220.  
  221. begin
  222.      if sw.ForceNull and (str[length(str)] <> #0) then
  223.           Validate := false
  224.      else
  225.      if SW.English then 
  226.      begin
  227.      { routine to check the string for >= one consonant
  228.        & >= one vowel }
  229.           foundc := false;
  230.           foundv := false;
  231.           I := 1;
  232.           repeat
  233.                foundv := foundv or (upcase(str[I]) in 
  234.                     ['A','E','I','O','U','Y']);
  235.                foundc := foundc or (upcase(str[I]) in 
  236.                     ['B'..'D','F'..'H','J'..'N','P'..'T','V'..'Z']);
  237.                inc(I)
  238.           until (foundv and foundc) or (I > length(str));
  239.           Validate := foundv and foundc
  240.      end
  241.      else Validate := true
  242. end;
  243.  
  244. procedure massage(var str: maxstring);
  245.  
  246. { Perform changes to the string which can be most efficiently done
  247.   all at once.  Currently we